// 知识图谱初始化方法集合
import * as d3 from "d3";
import $ from "jquery";
import * as DEFAULT from "@/utils/graph/default";
import { Simulation } from "@/utils/graph/Simulation";
import { Zoom } from "@/utils/graph/Zoom";
import { Drawer } from "@/utils/graph/Drawer";
import { DataFomatter } from "@/utils/graph/DataFamtter";
import { EventManager } from "@/utils/graph/EventManager";
import { ElementEditor } from "@/utils/graph/ElementEditor";
import { TypeManager } from "@/utils/graph/TypeManager";
import { ButtonGroupManager } from "@/utils/graph/ButtonGroupManager";
import { HistoryManager } from "@/utils/graph/HistoryManager";
// import { Node } from "@/utils/graph/Node";
// import { Link } from "@/utils/graph/Link"

export function Initializer(ctx) {

  let context = ctx;

  /** ----------------------------------------------------------------------------
   * 知识图谱初始化入口方法
   * @param nameMapInfo
   * @param isFullscreen
   */
  this.initKG = function(nameMapInfo,isFullscreen) {

    //--- 规范化数据格式 ---
    mapName(nameMapInfo);

    initVisibleArr();

    context.kgInfo.isFullscreen = isFullscreen;

    //--- 初始化ElementEditor
    context.elementEditor = new ElementEditor(context);

    //--- 初始化ButtonGroupManager
    context.buttonGroupManager = new ButtonGroupManager(context);

    //--- 初始化TypeList
    context.typeManager = new TypeManager(context);
    // context.typeManager.initTypeList();

    //--- 初始化DataFormatter
    context.dataFormatter = new DataFomatter(context);

    //--- 初始化Drawer
    context.drawer = new Drawer(context);

    //--- 初始化Simulationd
    context.simulation = new Simulation(context);

    //--- 初始化Zoom
    context.zoom = new Zoom(context);

    //--- 初始化EventManager
    context.eventManager = new EventManager(context);

    //--- 初始化历史记录管理对象
    context.historyManager = new HistoryManager(context);

  }

  /**---------------------------------------------------------------------------
   * 渲染画布
   */
  this.display = function() {

    initGraphContainer(context);

    initMaker(context);

    context.typeManager.initType();

    context.dataFormatter.formatData();

    context.drawer.drawAll();

    context.simulation.initSimulation();

    context.zoom.initZoom();

    context.eventManager.initDefaultEvent();

    context.historyManager.initHistoryList();

  }

  /** --------------------------------------------------------------------------
   * 初始化绘图画布
   * @param context
   * @param isFullscreen
   */
  function initGraphContainer(context) {
    let _this = context;

    _this.gcontainer = d3.select("#" + _this.gid);

    _this.width = $("#" + _this.gid).width();
    _this.height = $("#" + _this.gid).height();

    // if (context.kgInfo.isFullscreen) {
    //   _this.width = window.screen.availWidth;
    //   _this.height = window.screen.availHeight;
    // } else {
    //   _this.width = $("#" + _this.gid).width();
    //   _this.height = $("#" + _this.gid).height();
    // }

    let sWidth = _this.width;
    let sHeight = _this.height;

    _this.svg = _this.gcontainer.append("svg");
    _this.svg.style("background-color", DEFAULT.BACKGROUND_COLOR);
    _this.svg.style("width", "100%");
    _this.svg.style("height", "100%");
    // _this.svg.attr("width", sWidth);
    // _this.svg.attr("width", sWidth);
    // _this.svg.attr("height", sHeight-70);
    _this.svg.attr("viewBox", "0 0 " + sWidth / 2 + " " + sHeight / 2);
    _this.svg.attr("id", "svg_idx");
    _this.svg.attr("preserveAspectRatio", "xMidYMidmeet");

    //这里的声明顺序也是图像的z轴顺序
    _this.qaGraphLink = _this.svg.append("g").attr("class", "line");
    _this.qaGraphLinkText = _this.svg.append("g").attr("class", "linetext");
    _this.qaGraphNode = _this.svg.append("g").attr("class", "node");
    _this.qaGraphNodeText = _this.svg.append("g").attr("class", "nodetext");
    _this.nodebuttonGroup = _this.svg.append("g").attr("class", "nodebutton");

    console.log("--- finish initGraphContainer ---");
  }

  /** 初始化绘制箭头模型方法 */
  function initMaker(context) {
    let arrowMarker = context.svg
      .append("marker")
      .attr("id", "arrow")
      .attr("markerUnits", "strokeWidth")
      .attr("markerWidth", "12") //
      .attr("markerHeight", "12")
      .attr("viewBox", "0 0 12 12")
      .attr("refX", "38")
      .attr("refY", "6")
      .attr("orient", "auto");
    let arrowPath = "M2,2 L10,6 L2,10 L6,6 L2,2"; // 定义箭头形状
    arrowMarker
      .append("path")
      .attr("d", arrowPath)
      .attr("fill", DEFAULT.MARKER_COLOR);

    console.log("--- finish initMaker ---");
  }

  /** ----------------------------------------------------------------------------
   * 规范化对象内部名称
   * @param context
   * @param nameMapInfo
   */
  function mapName(nameMapInfo){
    if(context.kgInfo.nameMaped) return;

    let kg = context.kgInfo;

    kg.nameMaped = true;

    if(kg[nameMapInfo.kgNameName])
      exchangeName(kg,nameMapInfo.kgNameName,"name");
    else kg["name"] = "unknownKG";

    if(kg[nameMapInfo.kgID])
      exchangeName(kg,nameMapInfo.kgID,"id");
    else kg["id"] = -1;

    //规范化节点数组与关系数组名称
    exchangeName(kg,nameMapInfo.nodesName,"nodes");
    exchangeName(kg,nameMapInfo.linksName,"links");
    exchangeName(kg,nameMapInfo.kgNameName,"name");
    exchangeName(kg,nameMapInfo.kgIdName,"id");
    exchangeName(kg,nameMapInfo.typeListName,"typeList");

    //
    kg.typeList.forEach(function(type) {
      exchangeName(type,nameMapInfo.typeIdName,"id");
      exchangeName(type,nameMapInfo.typeNameName,"name");
      exchangeName(type,nameMapInfo.typeColorName,"selfColor");
      exchangeName(type,nameMapInfo.typeRName,"selfR");
      if(type.selfColor=="")type.selfColor=null;
      if(type.selfR==-1)type.selfR=null;
    });

    //规范化节点名称
    kg.nodes.forEach(function(node) {
      exchangeName(node,nameMapInfo.nodeIdName,"uuid");
      exchangeName(node,nameMapInfo.nodeUriName,"uri");
      exchangeName(node,nameMapInfo.nodeLabelName,"label");
      exchangeName(node,nameMapInfo.nodeTypeIdName,"typeId");
      exchangeName(node,nameMapInfo.nodeColorName,"selfColor");
      exchangeName(node,nameMapInfo.nodeRName,"selfR");
      exchangeName(node,nameMapInfo.nodeXName,"fx");
      exchangeName(node,nameMapInfo.nodeYName,"fy");
      if(node.fx == -1)node.fx = null;
      if(node.fy == -1)node.fy = null;
      if(node.selfColor == "")node.selfColor=null;
      if(node.selfR == -1)node.selfR=null;
    });

    //规范化连接名称
    kg.links.forEach(function(link) {
      exchangeName(link,nameMapInfo.linkIdName,"uuid");
      exchangeName(link,nameMapInfo.predicateName,"predicate");
      exchangeName(link,nameMapInfo.sIdName,"sId");
      exchangeName(link,nameMapInfo.tIdName,"tId");
    });

  }

  /**---------------------------------------------------------------------------
   * 初始化可见节点数组
   */
  function initVisibleArr() {
    context.kgInfo.visibleNodes = [];
    context.kgInfo.visibleLinks = [];

    context.kgInfo.nodes.forEach(function(node) {
      if(node.hide) return;
      context.kgInfo.visibleNodes.push(node);
    })

    context.kgInfo.links.forEach(function(link) {
      if(link.hide) return;
      context.kgInfo.visibleLinks.push(link);
    })
  }

  /** ----------------------------------------------------------------------------
   * 更换obj内指定变量名
   * @param obj
   * @param originName
   * @param targetName
   */
  function exchangeName(obj,originName,targetName) {
    if(originName === targetName) return;
    if(!obj[originName]) return;
    obj[targetName] = obj[originName];
    delete obj[originName];
  }

}

